<?php
namespace Home\Service;
use Think\Controller;
// +----------------------------------------------------------------------
// | Date:2018年4月4日
// +----------------------------------------------------------------------
// | Author: EK_熊<1439527494@qq.com>
// +----------------------------------------------------------------------
// | Description: 此文件作用于****
// +----------------------------------------------------------------------
class ApplyService extends Controller{
    
    protected $start_stamp = '';
    protected $start_day = '';
    protected $start_year = '';
    
    protected $end_stamp = '';
    protected $end_day = '';
    
    protected $isadmin = false;
    protected $attDayModel = '';
    protected $model = '';
    
    protected $appInfo = [];
    
    
    public function __construct(){
        $this->attDayModel = D('AttendanceDay');
        $this->model = D('Apply');
    }
    
    /**
     * 传入工号，post提交数据，生成申请数据
     * @param unknown $sn
     * @param unknown $post
     * @param string $admin  是否后台使用，默认是false
     * date:2018年4月4日
     * author: EK_熊
     */
    public function create_apply_info($sn,$post,$admin=false){
        
        $this->isadmin = $admin;
        
        //前台申请的公共限制
        if (!$admin){
            //全部申请的开始时间最小时间点是，提交动作日期的前一天0点
            $start_time_min = date('Y-m-d',strtotime('-1 day'));
            if ($this->appInfo['start_time'] < $start_time_min) $this->error('很抱歉,提交时间不允许');
        }
        
        $this->start_stamp = strtotime($post['start_time']);
        $this->start_day = date('Y-m-d',$this->start_stamp);
        $this->start_year = date('Y',$this->start_stamp);
        
        $this->end_stamp = strtotime($post['end_time']);
        $this->end_day = date('Y-m-d',$this->end_stamp);
        
        
        $accountService = new AccountService();
        $userInfo = $accountService->get_user_by_field(['sn'=>$sn],'leader_uid');
        
        $clockTimeService = new ClockTimeService($post['start_time'],$post['end_time']);
        $vacation = $clockTimeService->get_intrval_work_time();
        
        //组装申请数据
        $this->appInfo = $userInfo+$vacation+$post;
        $this->appInfo['name'] = $userInfo['ep_name'];
        $this->appInfo['uid'] = $userInfo['ep_id'];
        $this->appInfo['is_admin'] = 1;
        $this->appInfo['leader_uid'] = intval($this->appInfo['leader_uid']);
        unset($this->appInfo['ep_name']);
        unset($this->appInfo['total_hour']);
        unset($this->appInfo['ep_id']);

        /* 全部假期类型,要剔除连续时间内的非工作日的分钟数 */
        if ($this->appInfo['type'] == 2) {
            $unworkday = get_intrval_unwork_time($this->appInfo['start_time'],$this->appInfo['end_time']);
            if ($unworkday){
                $this->appInfo['total_min'] = $this->appInfo['total_min']-$unworkday['total_min'];
                $this->appInfo['total_day'] = $this->appInfo['total_day']-$unworkday['total_day'];
            }
        }
        
        //做申请数据检查，检查公共项
        $this->_common_check();
        
        //做申请数据检查，检查个体项
        $vacate_type = '_vacate_type_'.$this->appInfo['vacate_type'];
        if (method_exists($vacate_type)) $this->$vacate_type();
        
        
        return $this->appInfo;
        
    }
    
    /**
     * 前台，后台的公共限制 
     * 
     * date:2018年4月4日
     * author: EK_熊
     */
    private function _common_check(){
        //结束时间要比开始时间大
        if ($this->start_stamp >= $this->end_stamp) $this->error('请输入正确的起止时间！');
       
        //外出除外，其他的申请不允许使用18:00作为开始时间
        if ($this->appInfo['vacate_type'] !== '200' && $this->appInfo['start_time'] >= "$this->start_day 18:00") {
            $this->error('18:00是下班时间，不能作为开始时间！');
        } 
        
        /*时间区间覆盖问题的数据检查,检查开始时间 */
        $isExist_s = $this->model->where([
            'sn'=>$this->appInfo['sn'],
            "_string"=>"start_time <= '{$this->appInfo['start_time']}' AND end_time >= '{$this->appInfo['start_time']}'",
            'status'=>1
            ])->find();
        if ($isExist_s) $this->error('您可能重复提交了，请修改[开始时间]再提交吧~');
        
        /* 时间区间覆盖问题的数据检查,检查结束时间 */
        $isExist_e = $this->model->where([
            'sn'=>$this->appInfo['sn'],
            "_string"=>"start_time <= '{$this->appInfo['end_time']}' AND end_time >= '{$this->appInfo['end_time']}'",
            'status'=>1
            ])->find();
    
        if ($isExist_e) $this->error('您可能重复提交了，请修改[结束时间]再提交吧~');
        
        /* 病假(全,半),年假，申请时间范围是当年的1月1日到12月31日 */
        if (in_array($this->appInfo['vacate_type'],['109','110','103']) ){
            if(($this->appInfo['start_time'] < "$this->start_year-01-01 00:00:00") || ($this->appInfo['end_time'] > "$this->start_year-12-31 23:59:59")){
                $this->error('很抱歉,日期不合法');
            }
        }
        
    }

    
    //短途外出
    private function _vacate_type_200(){
        //不能超过24小时
        if (($this->end_stamp - $this->start_stamp) > 86400) $this->error("短途外出不能超过24个小时");
        if (!$this->isadmin && empty($post['resaon_img'])) $this->error("请提交相关证明!");  //前台提交需要上附件  
    }
    
    
    //长途出差
    private function _vacate_type_201(){
        //必须大于24小时
        if ($this->appInfo['total_day'] <= 1) $this->error("长途出差不能小于24个小时");
        if (!$this->isadmin && empty($this->appInfo['resaon_img'])) $this->error("请提交OA截图!");
    }
    
    
    //加班：工作日/凌晨跨天
    private function _vacate_type_300(){
        $cfg_work_day = C('ACTUAL_WORK_DAY');
        $intrvalDay = date('d',$this->end_stamp)-date('d',$this->end_stamp);
        
        //不跨天的情况，1日期相同，2结束时间点小于配置的跨天时间点
        if ($intrvalDay == 0 || $this->appInfo['end_time'] <= "$this->end_day $cfg_work_day[1]") {
            $this->error("该申请仅适用于晚上连续加班超过第二天凌晨6点");
        }
        $map['date'] = $this->start_day;
        $map['sn'] = $this->appInfo['sn'];
        $isHavAtt = $this->attDayModel->where($map)->find();
        if (!$isHavAtt) {
            $this->error("当天没考勤数据，不允许提交申请！！");
        }
    }
    
    
    //加班：公休日
    private function _vacate_type_301(){
        if (is_work_day($this->start_day)) $this->error('开始日期必须是公休日~');
        
        if (is_work_day($this->end_days)) {
            if ($this->appInfo['end_time'] > "$this->end_day 06:00:00") {
                $this->error('结束日期必须是公休日~');
            }
        }
    }
    
    //调休
    private function _vacate_type_101(){
        if ($this->attInfo['overtime'] <= 0 ){
            $this->error("很抱歉，您没有可以调休的时间！");
        }
        
        //查询截止至开始时间的可补休时间
        $remain_overtime = $this->attDayModel->count_remain_overtime($this->user_sn,'',$this->start_day);
        
        if($this->appInfo['total_min'] > $remain_overtime) {
            $timeAllow = time_day_8hour_zh($remain_overtime);
            $this->error("很抱歉，截止{$this->start_day}为止,剩余可补休时间为{$timeAllow},调休时间不足！");
        }
   
    }
    
    
    //年假
    private function _vacate_type_103(){
        
        $remain = D('AnnualLeave')->remain_annual($this->appInfo['sn']);//获取剩余年假数
        if ($this->appInfo['total_min'] > $remain['total']) {
            $remainStr = time_day_8hour_zh($remain['total']);
            $this->error("很抱歉，您只能申请{$remainStr}年假！");
        }
    }
    
    
    //婚假
    private function _vacate_type_105(){
        //婚假申请时长上限是3天
        if ($this->appInfo['total_day'] > 3){
            $this->error('很抱歉,婚假上限是3天');
        }    
    }
    
    //病假 ： 全日薪
    private function _vacate_type_109(){
        $remain = D('AnnualLeave')->remain_sick($this->user_sn,$this->appInfo['vacate_type']);
        $remainStr = time_day_8hour_zh($remain);
        
        if ($this->appInfo['total_min'] > $remain) {
            $this->error("很抱歉，您只能申请{$remainStr}工时的全日薪病假！");
        }    
    }
    
    //病假 ： 半日薪
    private function _vacate_type_110(){
        $remain = D('AnnualLeave')->remain_sick($this->user_sn,$this->appInfo['vacate_type']);
        $remainStr = time_day_8hour_zh($remain);
        
        if ($this->appInfo['total_min'] > $remain) {
            $this->error("很抱歉，您只能申请{$remainStr}工时的半日薪病假！");
        }    
    }
    
    
    
}